home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / program / recio214.zip / RGET.C < prev    next >
C/C++ Source or Header  |  1996-06-14  |  23KB  |  629 lines

  1. /*****************************************************************************
  2.    MODULE: rget.c
  3.   PURPOSE: recio input functions
  4. COPYRIGHT: (C) 1994-1996, William Pierpoint
  5.  COMPILER: Borland C Version 3.1
  6.        OS: MSDOS Version 6.2
  7.   VERSION: 2.14
  8.   RELEASE: June 14, 1996
  9. *****************************************************************************/
  10.  
  11. #include <ctype.h>
  12. #include <errno.h>
  13. #include <limits.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include "recio.h"
  19.  
  20. extern int _risready(REC *rp, int mode);
  21. extern int _rmoderror(REC *rp, int mode);
  22. extern void _rsetexitfn(REC *rp);
  23.  
  24. /* private macros */
  25. #define RECBUFSIZ_MIN 2         /* min one character and new line */
  26. #define FLDBUFSIZ_MIN 1         /* min one character */
  27.  
  28. #define RECBUFSIZE    max(RECBUFSIZ, RECBUFSIZ_MIN)
  29. #define FLDBUFSIZE    max(FLDBUFSIZ, FLDBUFSIZ_MIN)
  30.  
  31. #define rcol(rp)         ((rp)->r_colno)
  32. #define rflags(rp)       ((rp)->r_flags)
  33. #define rfd(rp)          ((rp)->r_fd)
  34. #define rfp(rp)          ((rp)->r_fp)
  35. #define rreclen(rp)      ((rp)->r_reclen)
  36. #define rrecsiz(rp)      ((rp)->r_recsiz)
  37. #define rfldsiz(rp)      ((rp)->r_fldsiz)
  38. #define rfldch(rp)       ((rp)->r_fldch)
  39. #define rtxtch(rp)       ((rp)->r_txtch)
  40.  
  41. /****************************************************************************/
  42. static int                   /* return error number (0=no error)            */
  43.     _rsetfldsiz(             /* set field buffer size                       */
  44.         REC   *rp,           /* record pointer                              */
  45.         size_t fldsiz)       /* field buffer size                           */
  46. /****************************************************************************/
  47. {
  48.     int errnum=0;            /* error number */
  49.     char *fldp;              /* pointer to new field buffer */
  50.  
  51.     /* if no memory allocated to field buffer */
  52.     if (!rflds(rp)) {
  53.  
  54.         /* determine minimum size of field buffer */
  55.         fldsiz = max(fldsiz, FLDBUFSIZE);
  56.  
  57.         /* initially allocate memory for field buffer */
  58.         do {
  59.             fldp = (char *) calloc(fldsiz+1, sizeof(char));
  60.             if (!fldp) {
  61.                 errnum = rseterr(rp, R_ENOMEM);
  62.                 if (errnum) goto done;
  63.             }
  64.         } while (!fldp);
  65.         rflds(rp) = fldp;
  66.         rfldsiz(rp) = fldsiz;
  67.         _rsetexitfn(rp);
  68.  
  69.     /* if field buffer needs to be larger */
  70.     } else if (fldsiz > rfldsiz(rp)) {
  71.  
  72.         /* reallocate memory for field buffer */
  73.         do {
  74.             fldp = (char *) realloc(rflds(rp), fldsiz+1);
  75.             if (!fldp) {
  76.                 errnum = rseterr(rp, R_ENOMEM);
  77.                 if (errnum) goto done;
  78.             }
  79.         } while (!fldp);
  80.         rflds(rp) = fldp;
  81.         rfldsiz(rp) = fldsiz;
  82.     }
  83.  
  84. done:
  85.     return errnum;
  86. }
  87.  
  88. /****************************************************************************/
  89. static int                   /* return error number (0=no error)            */
  90.     _rsetrecsiz(             /* set record buffer size                      */
  91.         REC   *rp,           /* record pointer                              */
  92.         size_t recsiz)       /* record buffer size                          */
  93. /****************************************************************************/
  94. {
  95.     int errnum=0;            /* error number */
  96.     char *recp;              /* pointer to new record buffer */
  97.  
  98.     /* if no memory allocated to field buffer */
  99.     if (!rrecs(rp)) {
  100.  
  101.         /* determine minimum size of record buffer */
  102.         recsiz = max(recsiz, RECBUFSIZE);
  103.  
  104.         /* initially allocate memory for record buffer */
  105.         do {
  106.             recp = (char *) calloc(recsiz+1, sizeof(char));
  107.             if (!recp) {
  108.                 errnum = rseterr(rp, R_ENOMEM);
  109.                 if (errnum) goto done;
  110.             }
  111.         } while (!recp);
  112.         rrecs(rp) = recp;
  113.         rrecsiz(rp) = recsiz;
  114.         _rsetexitfn(rp);
  115.  
  116.     /* if record buffer needs to be larger */
  117.     } else if (recsiz > rrecsiz(rp)) {
  118.  
  119.         /* reallocate memory for record buffer */
  120.         do {
  121.             recp = (char *) realloc(rrecs(rp), recsiz+1);
  122.             if (!recp) {
  123.                 errnum = rseterr(rp, R_ENOMEM);
  124.                 if (errnum) goto done;
  125.             }
  126.         } while (!recp);
  127.         rrecs(rp) = recp;
  128.         rrecsiz(rp) = recsiz;
  129.     }
  130.  
  131. done:
  132.     return errnum;
  133. }
  134.  
  135. /****************************************************************************/
  136. static int                   /* return !0 on match                          */
  137.     risfldch(                /* is character the field separator character? */
  138.         REC *rp,             /* record pointer                              */
  139.         int  ch)             /* character to test                           */
  140. /****************************************************************************/
  141. {
  142.     int ismatch=0;           /* return 0 if no match */
  143.  
  144.     if (isascii(ch)) { 
  145.         if (rfldch(rp) == ' ') {
  146.             ismatch = isspace(ch);
  147.         } else {
  148.             ismatch = (!(ch - rfldch(rp)));
  149.         }
  150.     }
  151.     return ismatch;
  152. }
  153.  
  154. /****************************************************************************/
  155. static int                   /* return !0 on match                          */
  156.     ristxtch(                /* is character the text delimiter character?  */
  157.         REC *rp,             /* record pointer                              */
  158.         int  ch)             /* character to test                           */
  159. /****************************************************************************/
  160. {
  161.     int ismatch=0;           /* return 0 if no match */
  162.  
  163.     if (isascii(ch)) { 
  164.         if (rtxtch(rp) == ' ') {
  165.             ismatch = isspace(ch);
  166.         } else {
  167.             ismatch = (!(ch - rtxtch(rp)));
  168.         }
  169.     }
  170.     return ismatch;
  171. }
  172.  
  173. /****************************************************************************/
  174. static size_t                /* return length of field                      */
  175.     _rfldlen(                /* get length of field                         */
  176.         REC *rp)             /* record pointer                              */
  177. /****************************************************************************/
  178. {
  179.     size_t len=0;            /* length of field (0=missing field) */
  180.     size_t col;              /* column location */
  181.     size_t co;               /* temporary column location */
  182.     int qstate=0;            /* nested quoted text state (0=off; 1=on) */
  183.  
  184.     /* clear quoted text char flag */
  185.     rflags(rp) &= ~_R_TXT;
  186.  
  187.     /* skip past any leading whitespace */
  188.     for (col=rcol(rp); col < rreclen(rp); col++) {
  189.         if (!isspace(rrecs(rp)[col])) break;
  190.     }
  191.  
  192.     /* is first non-whitespace character the txtch? */
  193.     if (ristxtch(rp, rrecs(rp)[col])) { /* yes, quoted text */
  194.         rflags(rp) |= _R_TXT;           /* set quoted text char flag  */
  195.         if (risfldch(rp, ' ')) {        /* fldch == ' '; txtch != ' ' */
  196.             /* skip over characters that are not txtch */
  197.             for (col++; col < rreclen(rp); col++) {
  198.                 /* if txtch, see if end-of-field */
  199.                 if (ristxtch(rp, rrecs(rp)[col])) {
  200.                     /* don't end field within any nested quoted text */
  201.                     if (ristxtch(rp, '"')) {
  202.                         qstate = !qstate;
  203.                         if (!qstate) continue;
  204.                     }
  205.                     /* if whitespace follows txtch, then end-of-field */
  206.                     if (isspace(rrecs(rp)[col+1])) {
  207.                         /* skip to end of trailing whitespace */
  208.                         for (col++; col < rreclen(rp); col++) {
  209.                             if (!isspace(rrecs(rp)[col])) {
  210.                                 col--;
  211.                                 break;
  212.                             }
  213.                         }
  214.                         break;
  215.                     }
  216.                 }
  217.             }
  218.         } else {                  /* fldch != ' ';